/*
 * AtomApplication.java
 *
 * Created on March 28, 2007, 12:20 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.atomojo.app;

import org.atomojo.app.auth.AuthService;
import org.atomojo.app.auth.UserGuard;
import org.atomojo.app.db.DB;
import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.Reference;
import org.restlet.routing.Filter;
import org.restlet.routing.Redirector;
import org.restlet.routing.Router;
import org.restlet.routing.Template;

/**
 *
 * @author alex
 */
public class AtomApplication extends Application{

   public static final Reference RESOURCE_BASE = new Reference("/R/");
   public static final Reference METADATA_BASE = new Reference("/M/");
   public static final Reference UPDATED_BASE = new Reference("/U/");
   public static final Reference TERM_BASE = new Reference("/T/");
   public static final Reference QUERY_BASE = new Reference("/Q/");

   public static final String AUTH_ATTR    = AtomApplication.class.getName()+".auth";
   public static final String DB_ATTR      = AtomApplication.class.getName()+".db";
   public static final String STORAGE_ATTR = AtomApplication.class.getName()+".storage";
   public static final String APP_ATTR = AtomApplication.class.getName()+".app";

   public static final String RESOURCE_BASE_ATTR = AtomApplication.class.getName()+"."+RESOURCE_BASE;
   public static final String METADATA_BASE_ATTR = AtomApplication.class.getName()+"."+METADATA_BASE;
   public static final String UPDATED_BASE_ATTR = AtomApplication.class.getName()+"."+UPDATED_BASE;
   public static final String TERM_BASE_ATTR = AtomApplication.class.getName()+"."+TERM_BASE;
   public static final String QUERY_BASE_ATTR = AtomApplication.class.getName()+"."+QUERY_BASE;

   Storage storage;
   DB atomDB;
   AuthService auth;
   boolean allowQueries;
   App app;
   
   /** Creates a new instance of AtomApplication */
   public AtomApplication(Context context,AuthService auth,DB atomDB,Storage storage,boolean allowQueries) {
      super(context.createChildContext());
      this.atomDB = atomDB;
      this.storage = storage;
      this.auth = auth;
      this.allowQueries = allowQueries;
      this.app = new App(context.getLogger(),atomDB,storage,getMetadataService());
      getContext().getAttributes().put(AUTH_ATTR,auth);
      getContext().getAttributes().put(DB_ATTR,atomDB);
      getContext().getAttributes().put(STORAGE_ATTR,storage);
      getContext().getAttributes().put(APP_ATTR,app);
      getContext().getAttributes().put(RESOURCE_BASE_ATTR,RESOURCE_BASE);
      getContext().getAttributes().put(METADATA_BASE_ATTR,METADATA_BASE);
      getContext().getAttributes().put(UPDATED_BASE_ATTR,UPDATED_BASE);
      getContext().getAttributes().put(TERM_BASE_ATTR,TERM_BASE);
      getContext().getAttributes().put(QUERY_BASE_ATTR,QUERY_BASE);
     getTunnelService().setEnabled(false);
   }

   public AuthService getAuthService() {
      return auth;
   }
   
   @Override
   public Restlet createRoot() {   
      Router router = new Router(getContext());
      router.setDefaultMatchingMode(Template.MODE_STARTS_WITH);
      Filter guard = new UserGuard(getContext(),ChallengeScheme.HTTP_BASIC,"Atom User",auth);
      guard.setNext(router);
      
      Redirector byId = new IdRedirector(getContext(),this,atomDB,RESOURCE_BASE);
      router.attach("/id/",byId);
      
      ProtocolByPathFinder byPath = new ProtocolByPathFinder(getContext(),this,RESOURCE_BASE,app,atomDB,storage);
      router.attach(RESOURCE_BASE.toString(),byPath);
      router.attach("/R",byPath);
      
      MetadataByPathFinder metadataByPath = new MetadataByPathFinder(getContext(),this,METADATA_BASE,RESOURCE_BASE,atomDB,storage);
      router.attach(METADATA_BASE.toString(),metadataByPath);
      
      router.attach(TERM_BASE.toString(),new TermFinder(getContext(),this,RESOURCE_BASE,atomDB,storage));
      
      if (allowQueries) {
         router.attach(QUERY_BASE.toString()+"adhoc/",AdHocQueryResource.class);
         router.attach(QUERY_BASE.toString(),new QueryFinder(getContext(),this,RESOURCE_BASE,atomDB,storage));
      }

      router.attach(UPDATED_BASE.toString(),UpdatedResource.class);
      
      router.attach("/",new Introspection(this,atomDB,storage,RESOURCE_BASE)).getTemplate().setMatchingMode(Template.MODE_EQUALS);
      
      return guard;
   }
   
}
